package camera;

import java.io.BufferedReader;
import java.io.IOException;
import java.net.DatagramSocket;
import java.net.ServerSocket;
import java.net.Socket;

import camerainterfaces.Axis211AInterface;
import camerainterfaces.FakeAxis211A;
import camerainterfaces.FakeMotionDetector;
import camerainterfaces.MotionDetectorInterface;
import camerainterfaces.ProxyAxis211A;
import camerainterfaces.ProxyMotionDetector;
import camerainterfaces.RealAxis211A;
import camerainterfaces.RealMotionDetector;

public class Main {

	public static String mode = "fake"; // Can be fake, real or proxy. Proxy
										// needs further config in ProxyConfig.

	public static void main(String args[]) {
		String name = args.length > 0 ? args[0] : "Camera";
		Axis211AInterface cam = null;
		MotionDetectorInterface motion = null;

		if (mode.equals("fake")) {
			cam = new FakeAxis211A();
			motion = new FakeMotionDetector();
		} else if (mode.equals("proxy")) {
			cam = new ProxyAxis211A();
			motion = new ProxyMotionDetector();
		} else if (mode.equals("real")) {
			cam = new RealAxis211A();
			motion = new RealMotionDetector();
		} else {
			System.err.println("Retarded message for a retarded user");
			System.err.println("-1");
		}

		if (!cam.connect()) {
			System.err.println("We are so screwed...");
			System.exit(-1);
		}
		ServerSocket listenCommandServer = null;
		ServerSocket motionServer = null;
		ServerSocket httpServer = null;
		Socket listenCommandSocket = null;
		DatagramSocket sendPictureSocket = null;
		Socket motionSocket = null;
		BufferedReader input = null;
		int listenCommandPort = 8001;
		int motionServerPort = 8002;
		int httpPort = 8080;
		while (true) {
			try {
				listenCommandServer = new ServerSocket(listenCommandPort);
				motionServer = new ServerSocket(motionServerPort);
				httpServer = new ServerSocket(httpPort);
				break; // When all servers have port we break the while.

			} catch (IOException e) { // this could be done prettier...
				System.err.println("port/ports in use: Changing ports");
				listenCommandPort += 3;
				motionServerPort += 3;
				httpPort += 1; // This one is not next to the others.
			}
		}
		System.out.println(name + ":");
		System.out.println("Command Port: " + listenCommandPort);
		System.out.println("Motion Port: " + motionServerPort);
		System.out.println("HTTP Port: " + httpPort);

		TinyHttpServer httpSrv = new TinyHttpServer(httpServer, cam);
		httpSrv.start();

		while (true) {
			try {
				listenCommandSocket = listenCommandServer.accept();
				motionSocket = motionServer.accept();
				sendPictureSocket = new DatagramSocket();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			CameraServer cs = new CameraServer(listenCommandSocket,
					sendPictureSocket, cam);
			MotionDetector md = new MotionDetector(40, motionSocket, motion);
			md.start();
			cs.start();
			try {
				cs.join();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			md.stop(); // TODO: CHECK IF THIS REALLY IS ALLOWED.........
			try {
				md.join();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}
}
